package main

import (
	"fmt"
	"math/rand"
	"os"
	"os/exec"
	"strconv"
	"time"
)

const (
	WIDTH  int = 43
	HEIGHT int = 22
)

var (
	arrMap [HEIGHT][WIDTH]int
	Nums   int = 0
)

func Cls() {
	cmd := exec.Command("cmd", "/c", "cls")
	cmd.Stdout = os.Stdout
	cmd.Run()
}

func CreateMap() {
	str := "吃到食物：" + strconv.Itoa(Nums) + "\r\n"
	for k1, v1 := range arrMap {
		for k2, v2 := range v1 {
			if v2 == 1 {
				if k1 == 0 || (k1 == HEIGHT-1) {
					if k2 == 0 {
						str += "#*"
					} else if k2 == (WIDTH - 1) {
						str += "#"
					} else {
						str += "*"
					}
				} else {
					if k2 == 0 {
						str += "|*"
					} else if k2 == (WIDTH - 1) {
						str += "|"
					} else {
						str += "*"
					}
				}
			} else {
				if k1 == 0 || (k1 == HEIGHT-1) {
					if k2 == 0 {
						str += "#-"
					} else if k2 == (WIDTH - 1) {
						str += "#"
					} else {
						str += "-"
					}
				} else {
					if k2 == 0 {
						str += "|_"
					} else if k2 == (WIDTH - 1) {
						str += "|"
					} else {
						str += "_"
					}
				}
			}
		}
		str += "\r\n"
	}
	fmt.Printf(str)
}

func RandFood() {
	valNum := 0
	for {
		rand.Seed(time.Now().UnixNano())
		y := rand.Intn(HEIGHT)
		x := rand.Intn(WIDTH)
		for _, v := range SinakeOne {
			if v.x == x || v.y == y {
				valNum += 1
			}
		}
		if valNum == 0 {
			arrMap[y][x] = 1
			FoodOne.x = x
			FoodOne.y = y
			break
		} else {
			continue
		}
	}
}

type Sinake struct {
	x int
	y int
}

var SinakeOne = make([]Sinake, 0, 100)

type Food struct {
	x int
	y int
}

var FoodOne Food

func ShowSinake() {
	y := 12
	x := 22
	arrMap[y][x] = 1
	SinakeOne = append(SinakeOne, Sinake{x, y})
}

func Run() {
	switch {
	case FoodOne.y < SinakeOne[0].y:
		SinakeOne = append(SinakeOne, Sinake{SinakeOne[0].x, SinakeOne[0].y - 1})
		arrMap[SinakeOne[0].y-1][SinakeOne[0].x] = 1
		arrMap[SinakeOne[0].y][SinakeOne[0].x] = 0
		SinakeOne = SinakeOne[1:]
	case FoodOne.y > SinakeOne[0].y:
		SinakeOne = append(SinakeOne, Sinake{SinakeOne[0].x, SinakeOne[0].y + 1})
		arrMap[SinakeOne[0].y+1][SinakeOne[0].x] = 1
		arrMap[SinakeOne[0].y][SinakeOne[0].x] = 0
		SinakeOne = SinakeOne[1:]
	case FoodOne.x < SinakeOne[0].x:
		SinakeOne = append(SinakeOne, Sinake{SinakeOne[0].x - 1, SinakeOne[0].y})
		arrMap[SinakeOne[0].y][SinakeOne[0].x-1] = 1
		arrMap[SinakeOne[0].y][SinakeOne[0].x] = 0
		SinakeOne = SinakeOne[1:]
	case FoodOne.x > SinakeOne[0].x:
		SinakeOne = append(SinakeOne, Sinake{SinakeOne[0].x + 1, SinakeOne[0].y})
		arrMap[SinakeOne[0].y][SinakeOne[0].x+1] = 1
		arrMap[SinakeOne[0].y][SinakeOne[0].x] = 0
		SinakeOne = SinakeOne[1:]
	default:
		Nums++
		FoodOne = Food{}
		RandFood()
	}
}

func main() {
	ShowSinake()
	RandFood()
	for {
		Run()
		CreateMap()
		time.Sleep(time.Millisecond * 50)
		Cls()
	}
	fmt.Println("蛇吃到了")
}
